package com.yzq.modular.core;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @ProjectName: modular
 * @Author: yzq
 * @Description: ${description}
 * @Date: 2022/4/16 19:31
 */
public abstract class AbstractRedisCacheOperator<T> implements CacheOperatorApi<T> {
    private final RedisTemplate<String, T> redisTemplate;

    public AbstractRedisCacheOperator(RedisTemplate<String, T> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void put(String key, T value) {
        this.redisTemplate.boundValueOps(this.calcKey(key)).set(value);
    }

    public void put(String key, T value, Long timeoutSeconds) {
        this.redisTemplate.boundValueOps(this.calcKey(key)).set(value, timeoutSeconds, TimeUnit.SECONDS);
    }

    public T get(String key) {
        return this.redisTemplate.boundValueOps(this.calcKey(key)).get();
    }

    public void remove(String... key) {
        ArrayList<String> keys = CollectionUtil.toList(key);
        List<String> withPrefixKeys = (List) keys.stream().map(this::calcKey).collect(Collectors.toList());
        this.redisTemplate.delete(withPrefixKeys);
    }

    public void expire(String key, Long expiredSeconds) {
        this.redisTemplate.boundValueOps(this.calcKey(key)).expire(expiredSeconds, TimeUnit.SECONDS);
    }

    public boolean contains(String key) {
        T value = this.redisTemplate.boundValueOps(this.calcKey(key)).get();
        return value != null;
    }

    public Collection<String> getAllKeys() {
        Set<String> keys = this.redisTemplate.keys(this.getCommonKeyPrefix() + "*");
        return (Collection) (keys != null ? (Collection) keys.stream().map((key) -> {
            return StrUtil.removePrefix(key, this.getCommonKeyPrefix());
        }).collect(Collectors.toSet()) : CollectionUtil.newHashSet(new String[0]));
    }

    public Collection<T> getAllValues() {
        Set<String> keys = this.redisTemplate.keys(this.getCommonKeyPrefix() + "*");
        return (Collection) (keys != null ? this.redisTemplate.opsForValue().multiGet(keys) : CollectionUtil.newArrayList(new Object[0]));
    }

    public Map<String, T> getAllKeyValues() {
        Collection<String> allKeys = this.getAllKeys();
        HashMap<String, T> results = MapUtil.newHashMap();
        Iterator var3 = allKeys.iterator();

        while (var3.hasNext()) {
            String key = (String) var3.next();
            results.put(key, this.get(key));
        }

        return results;
    }

    public RedisTemplate<String, T> getRedisTemplate() {
        return this.redisTemplate;
    }
}
